package org.webdb.webapp.resteasy;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;

import javax.ws.rs.ext.Provider;

import org.jboss.resteasy.spi.Registry;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.util.GetRestful;
import org.picocontainer.ComponentAdapter;
import org.picocontainer.MutablePicoContainer;
import org.picocontainer.PicoContainer;

public class PicoScanner {

    public void scanProviders(ResteasyProviderFactory providerFactory,
            PicoContainer picoContainer) {
        registerByTypeAnnotation(providerFactory, picoContainer, Provider.class);
    }

    @SuppressWarnings("unchecked")
    private void registerByTypeAnnotation(
            ResteasyProviderFactory providerFactory,
            PicoContainer picoContainer, Class<Provider> class1) {
        Collection<ComponentAdapter<?>> adapters = picoContainer
                .getComponentAdapters();
        adapters = filterTypeAnnotation(adapters, Provider.class);

        for (ComponentAdapter<?> adapter : adapters) {
            providerFactory.registerProviderInstance(adapter
                    .getComponentInstance(picoContainer,
                            adapter.getComponentImplementation()));
        }
    }

    private Collection<ComponentAdapter<?>> filterTypeAnnotation(
            Collection<ComponentAdapter<?>> adapters,
            Class<? extends Annotation>... annotations) {
        Class<?> clazz;
        Collection<ComponentAdapter<?>> filtered = new ArrayList<ComponentAdapter<?>>(
                adapters.size());
        for (ComponentAdapter<?> adapter : adapters) {
            clazz = adapter.getComponentImplementation();
            for (Class<? extends Annotation> annotation : annotations) {
                if (clazz.getAnnotation(annotation) != null) {
                    filtered.add(adapter);
                    break;
                }
            }
        }

        return filtered;
    }

    public void scanResources(Registry registry, MutablePicoContainer container) {
        for (ComponentAdapter<?> adapater : container.getComponentAdapters()) {
            if (GetRestful
                    .isRootResource(adapater.getComponentImplementation())) {
                registry.addResourceFactory(new PicoResourceFactory(adapater));
            }

        }
    }

}
